﻿using DG.Tweening;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public static class ToolFunction
{
    /// <summary>
    /// 获取Manager
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static T GetManager<T>() where T :ManagerBase
    {
       return GameRoot.Instance.managerService.GetManager<T>() as T;
    }
    /// <summary>
    /// 使用 Vector3 设置 itemIcon 的颜色
    /// </summary>
    /// <param name="img">需要设置颜色的 itemIcon 组件</param>
    /// <param name="colorVector">包含 RGB 值的 Vector3</param>
    /// <param name="alpha">透明度值（0 到 1之间）</param>
    public static void SetImageColorFromVector3(Image img, Vector3 colorVector, float alpha)
    {
        if (img == null)
        {
            Debug.LogWarning("itemIcon is null!");
            return;
        }

        // 确保 alpha 值在 0 到 1 之间
        alpha = Mathf.Clamp01(alpha);

        // 创建新的 Color，使用 Vector3 的分量作为 RGB，传入 alpha 值
        Color newColor = new Color(colorVector.x, colorVector.y, colorVector.z, alpha);

        // 设置 itemIcon 的颜色
        img.color = newColor;
    }

    public static void SetRawImageColorFromVector3(RawImage img, Vector3 colorVector, float alpha)
    {
        if (img == null)
        {
            Debug.LogWarning("itemIcon is null!");
            return;
        }

        // 确保 alpha 值在 0 到 1 之间
        alpha = Mathf.Clamp01(alpha);

        // 创建新的 Color，使用 Vector3 的分量作为 RGB，传入 alpha 值
        Color newColor = new Color(colorVector.x, colorVector.y, colorVector.z, alpha);

        // 设置 itemIcon 的颜色
        img.color = newColor;
    }
    public static void SetRawImageColorFromVector3(RawImage img, Color colorVector, float alpha)
    {
        if (img == null)
        {
            Debug.LogWarning("itemIcon is null!");
            return;
        }

        // 确保 alpha 值在 0 到 1 之间
        alpha = Mathf.Clamp01(alpha);

        // 创建新的 Color，使用 Vector3 的分量作为 RGB，传入 alpha 值
        Color newColor = colorVector;

        // 设置 itemIcon 的颜色
        img.color = newColor;
    }


    /// <summary>
    /// 计算角色正前方和目标角度的夹角,范围（-180，180）
    /// </summary>
    /// <param name="player"></param>
    /// <param name="toDir"></param>
    /// <returns></returns>
    public static float GetDeltaAngle(Transform player,float targetAngle)
    {
        Vector3 targetDir = Quaternion.Euler(0, targetAngle, 0) * Vector3.forward;
        return GetDeltaAngle(player, targetDir);
    }
    /// <summary>
    /// 计算角色正前方和目标方向的夹角,范围（-180，180）
    /// </summary>
    /// <param name="player"></param>
    /// <param name="toDir"></param>
    /// <returns></returns>
    public static float GetDeltaAngle(Transform player, Vector3 toDir)
    {
        return GetDeltaAngle(player.forward, toDir);
    }
    /// <summary>
    /// 计算两个向量得夹角，忽略Y向量，范围（-180，180）
    /// </summary>
    /// <param name="startDir"></param>
    /// <param name="toDir"></param>
    /// <returns></returns>
    public static float GetDeltaAngle(Vector3 startDir, Vector3 toDir)
    {
        float playerAngle = Mathf.Atan2(startDir.x, startDir.z) * Mathf.Rad2Deg;
        float targetAngle = Mathf.Atan2(toDir.x, toDir.z) * Mathf.Rad2Deg;
        float angleDelta = Mathf.DeltaAngle(targetAngle, playerAngle);
        return angleDelta;//正负代表右左
    }
    /// <summary>
    /// 计算跳跃的初速度
    /// </summary>
    /// <returns></returns>
    public static float GetJumpInitVelocity(float jumpMaxHeight,float Gravity)
    {
        return Mathf.Sqrt(-2 * Gravity * jumpMaxHeight);
    }

    public static void FindRootFather(Transform child, LayerMask layerMask,ref Transform parent)
    {
        // 如果 child 为 null，直接返回 null
        if (child == null)
        {
            parent = null;
            return;
        }

        // 如果没有父级，或者父级的层级不匹配
        if (child.parent == null || ((layerMask & 1 << child.parent.gameObject.layer)) == 0)
        {
            parent = child;
        }
        else
        {
            // 递归调用，查找父级
            FindRootFather(child.parent, layerMask,ref parent);
        }
    }
    


    public static Transform FindNearest(Transform owner, List<Transform> targetList)
    {
        Transform target = null;
        float minValue = int.MaxValue;
        for (int i = 0; i < targetList.Count; i++)
        {
            if (Vector3.Distance(owner.position, targetList[i].position) < minValue)
            {
                target = targetList[i];
            }
        }
        return target;
    }
    /// <summary>
    /// 投篮API
    /// </summary>
    /// <param name="ForceManitugde"></param>
    /// <param name="origin"></param>
    /// <param name="target"></param>
    /// <param name="rb"></param>
    public static void ProjectileShooterShoot(float ForceManitugde, Vector3 origin, Vector3 target, Rigidbody rb,bool isLowToss = true)
    {
        Vector3 delta = target - origin;
        float h = delta.y;
        Vector3 horizontalDelta = new Vector3(delta.x, 0, delta.z);
        float d = horizontalDelta.magnitude;
        float g = Mathf.Abs(Physics.gravity.y);
        float v0 = ForceManitugde / rb.mass;
        float a = (g * d * d) / (2 * v0 * v0);
        float b = -d;
        float c = h + a;
        float discriminant = b * b - 4 * a * c;
        Vector3 launchDir;
        Vector3 horizontalDir = horizontalDelta.normalized;
        if (discriminant >= 0 && d > 0.001f)
        {
            float sqrtD = Mathf.Sqrt(discriminant); ;
            float t1 = (-b + sqrtD) / (2 * a);
            float t2 = (-b - sqrtD) / (2 * a);
            float t;
            if (isLowToss)//低抛时间更少
            {
                t = Mathf.Min(t1, t2);
            }
            else
            {
                t = Mathf.Max(t1, t2);
            }
         
            float theta = Mathf.Atan(t);

            launchDir = horizontalDir * Mathf.Cos(theta) + Vector3.up * Mathf.Sin(theta);
        }
        else
        {
            launchDir = horizontalDir * Mathf.Cos(45) + Vector3.up * Mathf.Sin(45);
        }
        rb.transform.position = origin;
        rb.linearVelocity = Vector3.zero;
        rb.AddForce(launchDir * ForceManitugde, ForceMode.Impulse);
    }

    internal static void ProjectileShooterShoot(object forceMagnitude, Vector3 startPoint, Vector3 position, Rigidbody rigidbody, object isLowThrow)
    {
        throw new NotImplementedException();
    }
}